package com.uhylab.uhuvinetest.camera;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;

import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.util.Auth;
import com.uhylab.uhuvinetest.R;
import com.uhylab.uhuvinetest.qrcamera.activity.ResultActivity;
import com.uhylab.uhuvinetest.utils.UnzipAssets;

import org.json.JSONObject;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.android.JavaCameraView;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

public final class CaptureActivity extends Activity implements CvCameraViewListener2 {
    private static final String TAG = "CaptureActivity";
    private JavaCameraView mOpenCvCameraView;
    private ViewFindView viewFindView;

    private Mat mRgba;
    private Mat mGray;
    private static final int WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 201;
    private static final int CAMERA = 201;
    private boolean left;
    private boolean right;
    private boolean top;
    private boolean bottom;

    private float[] arrcolor = new float[48];
    private int[] weidong = new int[11];
    private int[] liuming = new int[11];

    private int is_load;
    private boolean is_destroy;


    private boolean to_camera = false;

    private long come_time;
    private ContentValues values;
    private boolean is_take = false;

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    AlertDialog ad = new AlertDialog.Builder(CaptureActivity.this).create();
                    ad.setCancelable(false);
                    ad.setMessage("您可以换一个环境进行检测.");
                    ad.setButton(DialogInterface.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
                    ad.show();

                    break;

                case 2:
                    final Bundle bundle = (Bundle) msg.obj;
                    handler.removeMessages(1);
                    AlertDialog callback = new AlertDialog.Builder(CaptureActivity.this).create();
                    callback.setCancelable(false);
                    callback.setMessage("是否检测成功?");
                    callback.setButton(DialogInterface.BUTTON_NEUTRAL, "确认", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            Intent intent = new Intent(CaptureActivity.this, ResultActivity.class);
                            intent.putExtras(bundle);
                            startActivity(intent);
                            finish();
                            dialog.dismiss();
                        }
                    });
                    callback.setButton(DialogInterface.BUTTON_NEGATIVE, "重拍", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            is_take = false;
                            viewFindView.findViewInvalidate(false, false, false, false);
                            handler.sendEmptyMessageDelayed(1, 30000);
                            dialog.dismiss();
                        }
                    });
                    callback.show();
                    break;
            }
            return false;
        }
    });
    private UploadManager uploadManager;
    private Mat isStop;

    public CaptureActivity() {
        Log.i(TAG, "Instantiated new " + this.getClass());
    }

    static {
        System.loadLibrary("opencv_java3");
        System.loadLibrary("mixed_sample");
    }

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        is_load = 0;
        setContentView(R.layout.tutorial1_surface_view);
        viewFindView = (ViewFindView) findViewById(R.id.viewFindView);

        getPermissions();

        if (to_camera) {
            mOpenCvCameraView = (JavaCameraView) findViewById(R.id.tutorial1_activity_java_surface_view);
            mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
            mOpenCvCameraView.setCvCameraViewListener(this);
        }

        OpenCVLoader.initDebug();

        is_destroy = false;

        is_load = 1;


    }

    /**
     * 获得相机 与 sd 卡权限
     */
    private void getPermissions() {
        ArrayList<String> strings = new ArrayList<>();

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //申请WRITE_EXTERNAL_STORAGE权限
            strings.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        } else {

        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            strings.add(Manifest.permission.CAMERA);
        } else {
            to_camera = true;
        }
        if (strings.size() > 0) {
            String[] MY_PERMISSIONS = new String[strings.size()];
            for (int i = 0; i < MY_PERMISSIONS.length; i++) {
                MY_PERMISSIONS[i] = strings.get(i);
            }
            ActivityCompat.requestPermissions(this,
                    MY_PERMISSIONS,
                    WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
        }
    }

    private void initHandler() {
        handler.sendEmptyMessageDelayed(1, 30000);
    }


    @Override
    public void onPause() {
        super.onPause();
        if (mOpenCvCameraView != null) {
            mOpenCvCameraView.disableView();
        }
        if (handler != null) {
            handler.removeMessages(1);
        }

    }

    @Override
    public void onResume() {
        super.onResume();
        if (is_load == 1 && to_camera) {
            mOpenCvCameraView.enableView();
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null) {
            mOpenCvCameraView.disableView();
        }
    }

    public void onCameraViewStarted(int width, int height) {
        initHandler();
        come_time = System.currentTimeMillis();
        String path = getExternalFilesDir(null).getPath();
        Log.e(TAG, path);
        DetectInit(path + "/Uhylab");


    }

    public void onCameraViewStopped() {

        if (!is_destroy) {
            DetectRelease();
            is_destroy = true;
        }
    }

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {


        mRgba = inputFrame.rgba();
        Mat clone = mRgba.clone();
        mGray = inputFrame.gray();

        left = false;
        right = false;
        top = false;
        bottom = false;

        if ((System.currentTimeMillis() - come_time > 3000)) {

            if (FindFeatures(mGray.getNativeObjAddr(), mRgba.getNativeObjAddr(), mRgba.getNativeObjAddr(), 240, 320)) {
                viewFindView.findViewInvalidate(left, right, top, bottom);
                if (!is_take) {
                    takePhoto(clone, arrcolor, weidong, liuming);
                     isStop = mRgba.clone();
                    is_take = true;
                }
            }
        }
        if (is_take) {
            return isStop;
        }

        return mRgba;
    }

    // A matrix that is used when saving photos.
    private Mat mBgr;

    private void takePhoto(final Mat rgba, final float[] floats, final int[] weidong, final int[] liuming) {
        mBgr = new Mat();
        // Determine the path and metadata for the photo.
        final long currentTimeMillis = System.currentTimeMillis();
        final String appName = getString(R.string.sd_files);
        final String img_files = getString(R.string.img_files);
        final String galleryPath =
                Environment.getExternalStorageDirectory().getPath();
        Log.e(TAG, galleryPath);
        final String albumPath = galleryPath + File.separator +
                appName + File.separator + img_files;
        final String photoPath = albumPath + File.separator +
                currentTimeMillis + LabString.PHOTO_FILE_EXTENSION;
        values = new ContentValues();

        values.put(MediaStore.MediaColumns.DATA, photoPath);
        values.put(MediaStore.Images.Media.MIME_TYPE,
                LabString.PHOTO_MIME_TYPE);
        values.put(MediaStore.Images.Media.TITLE, appName);
        values.put(MediaStore.Images.Media.DESCRIPTION, appName);
        values.put(MediaStore.Images.Media.DATE_TAKEN, currentTimeMillis);

        // Ensure that the album directory exists.
        File album = new File(albumPath);
        if (!album.isDirectory() && !album.mkdirs()) {
            Log.e(TAG, "Failed to create album directory at " +
                    albumPath);
            onTakePhotoFailed();
            return;
        }

        // Try to create the photo.
        Imgproc.cvtColor(rgba, mBgr, Imgproc.COLOR_RGBA2BGR, 3);


        if (!Imgcodecs.imwrite(photoPath, mBgr)) {
            Log.e(TAG, "Failed to save photo to " + photoPath);
            onTakePhotoFailed();
        }

        //获得bitmap，然后上传到7牛图片库
        new Thread(new Runnable() {
            @Override
            public void run() {
                shareToQiNiu(photoPath);
            }
        }).start();


        // Try to insert the photo into the MediaStore.

        /**
         * 三星 s7 6.01 无法获得
         * */

        try {
            getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } catch (final Exception e) {
            Log.e(TAG, "Failed to insert photo into MediaStore");
            e.printStackTrace();
            // Since the insertion failed, delete the photo.
            File photo = new File(photoPath);
            if (!photo.delete()) {
                Log.e(TAG, "Failed to delete non-inserted photo");
            }
            onTakePhotoFailed();
            return;
        }

        Message message = new Message();
        message.what = 2;
        Bundle bundle = new Bundle();
        bundle.putString("IMG_URI", photoPath);
        bundle.putFloatArray("colors", floats);
        bundle.putIntArray("weidong", weidong);
        bundle.putIntArray("liuming", liuming);
        message.obj = bundle;
        handler.sendMessage(message);




    }

    private void shareToQiNiu(String photoPath) {
        Bitmap bitmap = BitmapFactory.decodeFile(photoPath);
        uploadManager = new UploadManager();

//        String key = "o6x3cg1ob.bkt.clouddn.com";
        String key = System.currentTimeMillis() + ".jpg";
//        String token = "kcgvVCy6Be-ZGkUozogIc5ADKIDpNPLnkgMS5dno:YgT_FWXH9aezJSWxVdmTcRzuZNo=:eyJzY29wZSI6ImZ1bnNlbGwiLCJkZWFkbGluZSI6MzIwNjU1MjI5N30=";
        //前一个参数是从七牛网站上得到的AccessKey,后一个参数是SecretKey
//        Auth auth=Auth.create("9-evan1giiLtSSLw7HEMfq2WhMkQXHsePNg6dlRB", "ucwETmRK6dJRfggvF57niTLDa36_u7a50-HjtbQ8");
//        //第一个参数是你建立的空间名称，第三个是时间长度(按毫秒算的，我这里写的是10年)
//        String token=auth.uploadToken("appimages", null, 1000*3600*24*12*10, null);

        String token = getUpToken0();


        uploadManager.put(Bitmap2Bytes(bitmap), key, token, new UpCompletionHandler() {
            @Override
            public void complete(String key,
                                 com.qiniu.android.http.ResponseInfo responseInfo,
                                 JSONObject jsonObject) {
                //Toast.makeText(getApplication(), "开始上传", Toast.LENGTH_SHORT).show();
                if (responseInfo.statusCode == 200) {
                    // Toast.makeText(getApplication(), "完成上传", Toast.LENGTH_SHORT).show();
                    Log.e("TAG", "图片上传完成");
                } else {
                    //Toast.makeText(getApplication(), "上传失败", Toast.LENGTH_SHORT).show();
                    Log.e("TAG", "图片上传七牛失败");
                }


            }
        }, null);
    }

    public byte[] Bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    //上传到七牛服务器获取token
    public String getUpToken0() {
        String AccessKey = "7SUyN94l62siLSIRrELupEA_9PakPx1ynxxuM93e";
        String SecretKey = "UiOqtbLYm2EdvMItnCDIozsAVxmm_-tXEO9F6vRs";
        Auth auth = Auth.create(AccessKey, SecretKey);
//        Auth auth = Auth.create("vickay",AccessKey, SecretKey);
        Log.e("TAG", auth.uploadToken("vickay"));

        //String token=auth.uploadToken("appimages", null, 1000*3600*24*12*10, null);

        return auth.uploadToken("vickay");
    }


    private void onTakePhotoFailed() {

        // Show an error message.
        final String errorMessage =
                "请检查写入权限与内存空间";
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(CaptureActivity.this, errorMessage,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            finish();
            if (mOpenCvCameraView != null) {
                mOpenCvCameraView.disableView();
                if (!is_destroy) {
                    DetectRelease();
                    is_destroy = true;
                }
            }
        }
        return false;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
            int length = permissions.length;
            for (int i = 0; i < length; i++) {
                if (permissions[i].equals(Manifest.permission.CAMERA)) {
                    if (grantResults.length > 0
                            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        to_camera = true;
                        if (mOpenCvCameraView == null) {
                            mOpenCvCameraView = (JavaCameraView) findViewById(R.id.tutorial1_activity_java_surface_view);
                            mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
                            mOpenCvCameraView.setCvCameraViewListener(this);
                            mOpenCvCameraView.enableView();
                        }

                    }

                } else if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    if (grantResults.length > 0
                            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    }
                }
            }
        }
    }

    //    private static native void nativeDetect(long thiz, long inputImage, long faces);
    public native boolean FindFeatures(long matAddrGr, long matAddrRgba, long b, int width, int height);

    public native void DetectInit(String path);

    public native void DetectRelease();

}
